Plotting with Matplotlib


In [1]:
import matplotlib.pyplot as plt
import numpy as np

# For presentation purposes only.
%matplotlib inline

Plotting Datapoints

Let's start by plotting four points:

  • (1, 4)
  • (2, 3)
  • (3, 6)
  • (5, 2)

In [2]:
x = [1, 2, 3, 5]    # List of x coordinates.
y = [4, 3, 6, 2]    # List of y coordinates.
y_error = [0.1, 0.5, .2, 0.25] # Errors associated with the y readings.

plt.scatter(x, y)
plt.show()       # Displays the plot.
plt.clf()        # Clears the plot.


<matplotlib.figure.Figure at 0x7fa1e1754450>

Three functions were called during the generation of this plot:

  • scatter: takes a list of x-coordinates and a list of y-coordinates and generates a scatterplot.
  • show: makes Python display the generated plot.
  • clf: clears the generated figure.

This plot is missing a couple of important features though:

  • Axes labels.
  • A title.
  • A background grid.

Let's fix that.


In [3]:
plt.scatter(x, y)
plt.xlabel("X Axis")
plt.ylabel("Y Axis")
plt.title("Basic Scatterplot")
plt.grid()

plt.show()
plt.clf()


<matplotlib.figure.Figure at 0x7fa1df56ffd0>

Let's say we wanted a line drawn between the points. Matplotlib has got us covered with the plot function.


In [4]:
plt.plot(x, y)
plt.xlabel("x")
plt.ylabel("y")
plt.title("Plot with Interpolated Lines")
plt.grid()

plt.show()
plt.clf()


<matplotlib.figure.Figure at 0x7fa1df4fcd50>

Matplotlib has gone ahead and interpolated a line between consecutive points. However it would be useful to still show the original points. This can be achieved using the marker keyword argument.


In [5]:
plt.plot(x, y, marker="D") # D is for diamond
plt.xlabel("x")
plt.ylabel("y")
plt.title("Plot with Interpolated Lines and Points Displayed")
plt.grid()

plt.show()
plt.clf()


<matplotlib.figure.Figure at 0x7fa1df5668d0>

There are lots of different marker styles available. A list of them can be found here.

Maplotlib has also given us some nice limits for our plot, however let's imaginge we needed the plot to show the origin.


In [6]:
plt.plot(x, y, marker="D")
plt.xlim([0, 5.2])    # Displays the x-axis from 0 to 4
plt.ylim([0, 6.4])    # Displays the y-axis from 0 to 7
plt.xlabel("x")
plt.ylabel("y")
plt.title("Plot Showing Origin")
plt.grid()

plt.show()
plt.clf()


<matplotlib.figure.Figure at 0x7fa1df7397d0>

This plot looks pretty good. Too good. Let's add in error bars using the errorbar function.


In [7]:
plt.plot(x, y, marker="x") # x is for x
plt.errorbar(x, y, yerr=y_error) # Adding in error bars.
plt.xlabel("x")
plt.ylabel("y")
plt.title("Realistic Plot")
plt.grid()

plt.show()
plt.clf()


<matplotlib.figure.Figure at 0x7fa1df746f50>

To specify x-errors use the xerr keyword.

Function Plotting


In [8]:
x = np.linspace(-np.pi, np.pi, 10, endpoint=True)
y = np.sin(x)

plt.plot(x, y, marker=".")
plt.xlabel("x")
plt.ylabel("sin(x)")
plt.title("Sine Function")
plt.grid()

plt.show()
plt.clf()


<matplotlib.figure.Figure at 0x7fa1df3d1990>

A whole bunch of stuff just happened. Let's take a minute to go through it:

  • np.pi: The numpy library has a value called pi, which conveniently stores the value of pi.
  • np.linspace: This function generates a list of 10 points between -pi and pi.
  • np.sin: sin function provided by the numpy library.

An important thing to wrap your head around is that plotting in Python is all about points. To plot a function you evaluate the function at many points and then plot those points. The plot above isn't particularly smooth. This can be improved by sampling more points.


In [9]:
x = np.linspace(-np.pi, np.pi, 100, endpoint=True) # Switch from 10 to 100 points.
y = np.sin(x)

plt.plot(x, y)
plt.xlabel("x")
plt.ylabel("sin(x)")
plt.title("Sine Function")
plt.grid()

plt.show()
plt.clf()


<matplotlib.figure.Figure at 0x7fa1df303ad0>

That looks much smoother. Now let's plot multiple figures in a single plot.


In [10]:
x = np.linspace(-np.pi, np.pi, 100, True)

plt.plot(x, np.sin(x))
plt.plot(x, np.cos(x))
plt.xlabel("x")
plt.ylabel("y")
plt.title("Sine and Cosine Function")
plt.grid()

plt.show()
plt.clf()


<matplotlib.figure.Figure at 0x7fa1df1e92d0>

This is as simple as making two calls to plot. However with two different things on the plot it's a good idea to label them.


In [11]:
x = np.linspace(-np.pi, np.pi, 100, True)

plt.plot(x, np.sin(x), label="Sin(x)") # label associates a name with the plot.
plt.plot(x, np.cos(x), label="Cos(x)")
plt.xlabel("x")
plt.ylabel("y")
plt.title("Sine and Cosine Function")
plt.legend(loc='upper left')    # Display the legend in the upper right.
plt.grid()
plt.show()
plt.clf()


<matplotlib.figure.Figure at 0x7fa1df33dd50>

And that's the general gist of generating plots.

Semilog and Log-Log Plots

Sometimes you want to have either the x-axis, y-axis or both as a log scale.


In [12]:
x = np.linspace(-100, 10, 100, True)

plt.plot(x, 10**x)
plt.xlabel("x")
plt.ylabel("y")
plt.title("Power Function")

plt.grid()
plt.show()


It's hard to see what's happening to see what's happening with this power function on a normal scale. Let's clean it up using a semi-log plot.


In [13]:
plt.semilogy(x, 10**x) # Semi-Log Plot
plt.xlabel("x")
plt.ylabel("y")
plt.title("Exponential Function - Semi-Log Plot")

plt.grid()
plt.show()


If you wanted the log scale on the x-axis you would use the semilogx function.

For log-log plots use the loglog function.


In [14]:
x = np.linspace(1, 10000, 50, True)

plt.loglog(x, x) # Log-log Plot
plt.xlabel("x")
plt.ylabel("y")
plt.title("Log-Log Plot")

plt.grid()
plt.show()


One thing to note is that when using a logarithmic scale, linspace isn't the best function to use because the distribution of sample points becomes skewed visually.


In [15]:
x = np.linspace(1, 10**3, 50, True)

plt.loglog(x, x, marker="x", linestyle='None')
plt.xlabel("x")
plt.ylabel("y")
plt.title("Skewed Log-Log")

plt.grid()
plt.show()


This can be improved by using the logspace function which takes as its first three arguments a starting power, ending power and the number of points to sample.


In [16]:
x = np.logspace(1, 3, 50, endpoint=True, base=10)

plt.loglog(x, x, marker="x", linestyle='None')
plt.xlabel("x")
plt.ylabel("y")
plt.title("Clean Log-Log")

plt.grid()
plt.show()


Saving Plots to a File

To including plots in reports, it's useful to be able to save them.


In [17]:
x = np.linspace(0, 10, 50)

plt.xlabel("x")
plt.ylabel("y")
plt.title("A Line")
plt.grid()
plt.plot(x, x)

plt.savefig("Line.pdf") # Save the plot.
plt.clf()


<matplotlib.figure.Figure at 0x7fa1defcd610>

Matplotlib determines what kind of file to save the plot as based on the extension you give the savefig function. In general you should be able to save plots with the following extensions:

  • png
  • pdf
  • ps
  • eps
  • svg